#!/bin/bash
#
# Create a disk image where there exists a partition whose sizes matches the
# start sector.
# brought up under bug 1807171, which describes an error in the sed expression
# used to generate the replacement partition map

set -e

TEMP_D=""

rq() {
    local out="${TEMP_D}/out"
    "$@" > "$out" 2>&1 || { echo "FAILED:" "$@"; cat "$out"; return 1; }
}
fail() { echo "FAILED:" "$@" 1>&2; exit 1; }

read_pt_info() {
    # read_pt_info(dump, <file><ptnum>, keyname)
    # parse sfdisk --dump output returning the value for keyname.
    # expecting to parse a single line like:
    #  disk.img2 : start=     1026048, size=     1026048,
    #     type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709,
    #     uuid=a0e1636e-b759-4e7a-bd14-6f3d6c04745d
    local file="$1" fpart="$2" key="$3"
    local cmd="" out=""
    cmd=(
        sed
        # delete any other line.
        -e "/^$fpart[ ]*:/!d"
        # match key=<spaces><value>,
        -e "s/.* $key[ ]*=[ ]*\([^, ]*\).*/\1/"
    )
    out=$("${cmd[@]}" "$file") ||
        { fail "failed command: ${cmd[*]}"; return 1; }
    _RET="$out"
}

setup_image() {
    sfdisk disk.img <<EOF
label: gpt
label-id: db24000c-6ef3-4a17-b71c-1064baa29514
device: disk.img
unit: sectors
first-lba: 2048
last-lba: 4194270

disk.img1 : start=        2048, size=     1024000, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, uuid=5bc16165-bfc0-4e13-94eb-b898dc0bca41
disk.img2 : start=     1026048, size=     1026048, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=a0e1636e-b759-4e7a-bd14-6f3d6c04745d
EOF
}

cleanup() {
    rm -rf "${TEMP_D}"
}

test_resize () {
    local resizer="$1" expected_start="$2" expected_size="$3"
    echo "====== Testing with resizer=$resizer ====="

    (
        cd ${TEMP_D}
        echo "$expected" > partitions.expected

        rq truncate "--size=2G" disk.img
        rq setup_image || fail "setup image $img"

        sfdisk --dump disk.img > partitions.before

        if ! GROWPART_RESIZER=$resizer \
                growpart -v -v disk.img 2 2>"stderr" > "stdout"; then
            cat "stderr" "stdout"
            fail "[resizer=$resizer] growpart failed"
        fi

        sfdisk --dump disk.img > partitions.after
        read_pt_info partitions.after disk.img2 start
        start=$_RET
        read_pt_info partitions.after disk.img2 size
        size=$_RET
        [ "$expected_start" = "$start" ] &&
            [ "$expected_size" = "$size" ] || {
            fail "$resizer failed. expected start/size != found start/size" \
                "($expected_start/$expected_size != $start/$size)"
        }
    )
}

TEMP_D=$(mktemp -d ${TMPDIR:-/tmp}/${0##*/}.XXXXXX)
trap cleanup EXIT

# the sfdisk and sgdisk resizers result in slightly different output,
# because of course they do.
test_resize sfdisk 1026048 3168223
test_resize sgdisk 1026048 3166208
